#ifndef _THREAD_H_
#define _THREAD_H_

#include "Thread_fwd.h"
#include "tools/HandleWraper.h"

#include <boost/shared_ptr.hpp>
#include <vector>
#include <limits>



namespace sd
{
namespace tools
{
namespace thread
{

class ThreadGroup;

namespace impl
{

class ThreadBase
{
public:
	ThreadBase();
	ThreadBase( int uid );
	ThreadBase( const HHANDLE& uid );
	~ThreadBase();

	void kill();
	void suspend();
	void resume();
	bool isSuspended();
	bool isFinished();

	bool operator ==(const ThreadBase& ref)const;
	bool operator !=(const ThreadBase& ref)const{ return !(*this==ref); }


protected:
	ThreadBase(const ThreadImplRef& ref){ add(ref); }

	friend class sd::tools::thread::ThreadGroup;

	iterator begin(){ return impl_.begin(); }
	const_iterator begin()const{ return impl_.begin(); }
	iterator end(){ return impl_.end(); }
	const_iterator end()const{ return impl_.end(); }



	ThreadImplRef& get(int index);
	const ThreadImplRef& get(int index)const;

	int find( const ThreadImplRef& )const;
	void clear(){ impl_.clear(); }
	void remove(int index);
	void add( const ThreadImplRef& );
	size_t size()const{ return impl_.size(); }
private:
	Impls impl_;
};

}




class Thread : public impl::ThreadBase
{
public:
	Thread();
	Thread( int uid );
	Thread( const HHANDLE& uid );

	int getId()const;
	const void* getCurrentEIP()const;

	void join();
	bool timed_join(int msec_time);

	bool operator ==( const Thread& ref )const{ return ((impl::ThreadBase&)*this)==ref; }
	bool operator !=( const Thread& ref )const{ return ((impl::ThreadBase&)*this)!=ref; }

protected:
	friend class ThreadGroup;
	Thread(const ThreadImplRef& ref):ThreadBase(ref){}
};


class ThreadGroup : public impl::ThreadBase
{
public:
	ThreadGroup(){}
	void CreateThread( int uid );
	void CreateThread( const HHANDLE& uid );

	void addThread(const Thread&);
	void removeThread(const Thread&);
	void addGroup(const ThreadGroup& group);
	void removeGroup(const ThreadGroup& group);

	size_t count()const{ return size(); }
	Thread get(int index);
	Thread get(int index)const;

	int find( const Thread& thread );
	void clear(){ impl::ThreadBase::clear(); }


	void join( bool wait_all );
	bool timed_join(int msec_time,  bool wait_all );
};





}//thread
}//tools
}//sd















#endif//_THREAD_H_